﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using GalaSoft.MvvmLight;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Command;
using System.IO;
using System.Xml.Linq;
using LogViewApp.Models;
using System.Collections.Generic;
using System.Windows.Threading;
using LogViewApp.Controls;

namespace LogViewApp.ViewModel
{
    public class HomeViewModel:ViewModelBase
    {
#region properties        

        public Home owner;
        private int _maxFileSize = int.MaxValue;

        private FileCollection _files;
        public FileCollection files
        {
            get
            {
                if (_files == null)
                {
                    _files = new FileCollection(_customParams, _maxUpload);
                }
                return _files;
            }
        }
        public event EventHandler MaximumFileSizeReached;
        private int _maxUpload = 2;
        private string _customParams;
        private string _fileFilter;
        private bool _HttpUploader = false;
        private string _uploadHandlerName;

        private bool _WindowsAzureBlobUploader = true;
        private string _uploadContainerUrl;



        private string _AddFileName = string.Empty;
        public string AddFileName
        {
            get
            {
                return _AddFileName;
            }
            set
            {
                if (_AddFileName == value)
                    return;
                _AddFileName = value;
                RaisePropertyChanged("AddFileName");
            }
        }


        #region Template
        /*
        private string _NewPropName = string.Empty;
        public string NewPropName
        {
            get
            {
                return _NewPropName;
            }
            set
            {
                if (_NewPropName == value)
                    return;
                _NewPropName = value;
                RaisePropertyChanged("NewPropName");
            }
        }
         * */
        #endregion

        private ObservableCollection<logFileEntry> _fileList;
        public ObservableCollection<logFileEntry> fileList
        {
            get
            {
                if (_fileList == null)
                {
                    _fileList = new ObservableCollection<logFileEntry>();
                    GetMainPage().SetLogFileList(_fileList);
                    
                }
                return _fileList;
            }
            set
            {
                if (_fileList == value)
                    return;
                _fileList = value;
                RaisePropertyChanged("fileList");
            }
        }

#endregion

        public class logFileEntry
        {
            public string fileName;
            public XElement xLogFile;
            public bool hasView = false;
            public Guid guid;
            public long fileSize;
            public override string ToString()
            {
                string fileSizeString;
                if (fileSize >= 1024 * 1024)
                {
                    fileSizeString = string.Format("{0} MB", fileSize / 1024 / 1024);
                }
                else if (fileSize >= 1024)
                {
                    fileSizeString = string.Format("{0} KB", fileSize / 1024);
                }
                else
                {
                    fileSizeString = string.Format("{0} Byte", fileSize);
                }
                return string.Format("FileName:{0}, FileSize:{1}", fileName, fileSizeString);
            }
        }

        private string _DropBoxText;
        public string DropBoxText
        {
            get
            {
                if (_DropBoxText == null)
                    _DropBoxText = "Drop install log xml files here";
                return _DropBoxText;
            }

            set
            {
                if (_DropBoxText == value)
                    return;
                _DropBoxText = value;
                RaisePropertyChanged("DropBoxText");
            }
        }

        private Brush _DropBoxTextColor;
        public Brush DropBoxTextColor
        {
            get
            {
                if (_DropBoxTextColor == null)
                {
                    _DropBoxTextColor = new SolidColorBrush(Colors.Gray);
                }
                return _DropBoxTextColor;
            }
            set
            {
                if (_DropBoxTextColor == value)
                    return;
                _DropBoxTextColor = value;
                RaisePropertyChanged("DropBoxTextColor");
            }
        }

#region Command
        private RelayCommand _UploadSingleCmd;
        public RelayCommand UploadSingleCmd
        {
            get
            {
                if (_UploadSingleCmd == null)
                {
                    _UploadSingleCmd = new RelayCommand(()=>
                        {
                            MessageBox.Show("Wow, single");
                        });
                }
                return _UploadSingleCmd;

            }
        }
        
        private RelayCommand _UploadCmd;
        public RelayCommand UploadCmd
        {
            get
            {
                if (_UploadCmd == null)
                {
                    _UploadCmd = new RelayCommand(() =>
                        {
                            if (files.Count == 0)
                            {
                                MessageChildWindow messageWindow = new MessageChildWindow();
                                messageWindow.Message = "No files to upload. Please select one or more files first.";
                                messageWindow.Show();
                            }
                            else
                            {
                                //Tell the collection to start uploading
                                files.UploadFiles();
                            }
                        });
                }
                return _UploadCmd;
            }
        }

        private RelayCommand _ClearCmd;
        public RelayCommand ClearCmd
        {
            get
            {
                if (_ClearCmd == null)
                {
                    files.Clear();
                }
                return _ClearCmd;
            }
        }

        private RelayCommand _BrowseFileCmd;
        public RelayCommand BrowseFileCmd
        {
            get
            {
                if (_BrowseFileCmd == null)
                {
                    _BrowseFileCmd = new RelayCommand(() =>
                        {
                            OpenFileDialog ofd = new OpenFileDialog();
                            ofd.Filter = "Install Log File(*.xml)|*.xml|All files(*.*)|*.*";
                            ofd.Multiselect = true;
                            if (ofd.ShowDialog() == true)
                            {
                                foreach (FileInfo fi in ofd.Files)
                                {
                                    //AddFileToList(fi, fileList);
                                    AddFileToUploadList(fi);
                                }
                            }
                        });
                }
                return _BrowseFileCmd;
            }
        }


        private RelayCommand<logFileEntry> _ViewCmd;
        public RelayCommand<logFileEntry> ViewCmd
        {
            get
            {
                if (_ViewCmd == null)
                {
                    _ViewCmd = new RelayCommand<logFileEntry>((logFileEntry item ) =>
                        {
                            if (item == null)
                                return;
                            if (!item.hasView)
                            {
                                GetMainPage().AddLogViewtoFramework(item.fileName, item.guid);
                                item.hasView = true;
                            }
                            GetMainPage().NagivateToLogView(item.fileName, item.guid);
                        });
                }
                return _ViewCmd;
            }

        }

#endregion

        public HomeViewModel()
        {
            App app = Application.Current as App;
            LoadConfiguration(app.initParams);
        }

        internal void HandleFileDrop(FileInfo[] fileInfos)
        {
            foreach (var fi in fileInfos)
            {
                //AddFileToList(fi, fileList);
                AddFileToUploadList(fi);
            }
            DropBoxText = "Drop install log xml files here";
            DropBoxTextColor = new SolidColorBrush(Colors.Gray);
        }

        internal void AddFileToUploadList(FileInfo file)
        {
            string fileName = file.Name;

            //Create a new UserFile object
            UserFile userFile = new UserFile();
            userFile.FileName = file.Name;
            userFile.FileStream = file.OpenRead();
            userFile.UIDispatcher = this.owner.Dispatcher ;
            userFile.HttpUploader = _HttpUploader;
            userFile.UploadHandlerName = _uploadHandlerName;
            userFile.WindowsAzureBlobUploader = _WindowsAzureBlobUploader;
            userFile.UploadContainerUrl = _uploadContainerUrl;
            userFile.StorageState = Constants.StorageState.Local;
            //Check for the file size limit (configurable)
            if (userFile.FileStream.Length <= _maxFileSize)
            {
                //Add to the list
                files.Add(userFile);
            }
            else
            {
                MessageChildWindow messageWindow = new MessageChildWindow();
                messageWindow.Message = "Maximum file size is: " + (_maxFileSize / 1024).ToString() + "KB.";
                messageWindow.Show();

                if (MaximumFileSizeReached != null)
                    MaximumFileSizeReached(this, null);

            }

        }

        //internal static void AddFileToList(FileInfo fi, ObservableCollection<logFileEntry>_fileList)
        //{
        //    string addedFileName = fi.Name;
        //    XElement xLogFileTemp;
        //    try
        //    {
        //        string addedFileContent;
        //        StreamReader sr = fi.OpenText();
        //        addedFileContent = sr.ReadToEnd();
        //        xLogFileTemp = XElement.Parse(addedFileContent);
        //    }
        //    catch (System.IO.FileLoadException exp)
        //    {
        //        MessageBox.Show("File not found exception:" + exp.Message);
        //        return;
        //    }
        //    catch (Exception exp)
        //    {
        //        MessageBox.Show("drop file cause a exception:" + exp.Message);
        //        return;
        //    }

        //    logFileEntry newEntry = new logFileEntry { fileName = addedFileName, xLogFile = xLogFileTemp, guid = Guid.NewGuid(), fileSize=fi.Length};
        //    _fileList.Add(newEntry);

        //}

        internal MainPage GetMainPage()
        {
            Activity act = Application.Current.RootVisual as Activity;
            MainPage mainPage = act.Content as MainPage;
            return mainPage;
        }

        internal void HandleFileDropEnter()
        {
            DropBoxText = "Only XML format is allowed !";
            DropBoxTextColor = new SolidColorBrush(Colors.Red);
        }

        internal void HandleFileDropLeave()
        {
            DropBoxText = "Drop install log xml files here";
            DropBoxTextColor = new SolidColorBrush(Colors.Gray);
        }

        /// <summary>
        /// Load configuration first from initParams, then from .Config file
        /// </summary>
        /// <param name="initParams"></param>
        private void LoadConfiguration(IDictionary<string, string> initParams)
        {
            string tryTest = string.Empty;

            //Load Custom Config String
            if (initParams.ContainsKey("CustomParam") && !string.IsNullOrEmpty(initParams["CustomParam"]))
                _customParams = initParams["CustomParam"];

            if (initParams.ContainsKey("MaxUploads") && !string.IsNullOrEmpty(initParams["MaxUploads"]))
            {
                int.TryParse(initParams["MaxUploads"], out _maxUpload);
            }

            if (initParams.ContainsKey("MaxFileSizeKB") && !string.IsNullOrEmpty(initParams["MaxFileSizeKB"]))
            {
                if (int.TryParse(initParams["MaxFileSizeKB"], out _maxFileSize))
                    _maxFileSize = _maxFileSize * 1024;
            }

            if (initParams.ContainsKey("FileFilter") && !string.IsNullOrEmpty(initParams["FileFilter"]))
                _fileFilter = initParams["FileFilter"];

            if (initParams.ContainsKey("HttpUploader") && !string.IsNullOrEmpty(initParams["HttpUploader"]))
                if (bool.TryParse(initParams["HttpUploader"], out _HttpUploader))
                    _HttpUploader = bool.Parse(initParams["HttpUploader"]);

            if (initParams.ContainsKey("UploadHandlerName") && !string.IsNullOrEmpty(initParams["UploadHandlerName"]))
                _uploadHandlerName = initParams["UploadHandlerName"];

            if (initParams.ContainsKey("WindowsAzureBlobUploader") && !string.IsNullOrEmpty(initParams["WindowsAzureBlobUploader"]))
            {
                if (bool.TryParse(initParams["WindowsAzureBlobUploader"], out _WindowsAzureBlobUploader))
                {
                    _WindowsAzureBlobUploader = bool.Parse(initParams["WindowsAzureBlobUploader"]);
                }
            }

            if (initParams.ContainsKey("UploadContainerUrl") && !string.IsNullOrEmpty(initParams["UploadContainerUrl"]))
            {
                _uploadContainerUrl = initParams["UploadContainerUrl"];
            }
        }


    }

}
